Como usar modulos Parallel to Serie (74HC165) para aumentar el numero de puertos de entrada.
Datasheet 74HC165Pines 74HC165:
El modulo 74HC165 nos permite convertir multiples entradas (en paralelo) en una señal en serie.
Usamos principalmente 3 pines del 74HC165 para controlarlo.
Por lo tanto el funcionamiento es: usamos Latch para generar un snapshot de las entradas conectadas a los pines (A-H), generamos una señal de reloj Clock para hacer que el modulo envíe los bits del snapshot a traves del pin QH, recibimos esa información en el microcontrolador usando el protocolo SPI.
NOTA: En las entradas conectadas al modulo 74HC165 ponemos una resistencia de 10K ohm como pull-down.
#include <avr/io.h>
#include <util/delay.h>
void SPI_Init() {
DDRB |= (1 << PB5) | (1 << PB3) | (1 << PB2);
DDRB &= ~(1 << PB4);
// Habilita SPI, Modo Maestro, Velocidad fck/16
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0);
}
uint8_t read_74HC165() {
uint8_t data;
// Pulso en PL para cargar los datos paralelos
PORTB &= ~(1 << PB2);
//_delay_us(1); // Opcional? descomentar en caso de que el latch no funcione
PORTB |= (1 << PB2);
// Iniciar transmisión SPI (enviamos dummy data para recibir)
// En este caso lo único que necesitamos aquí es generar los pulsos de reloj para recibir la informacion.
SPDR = 0x00;
// Esperar a que termine la transferencia
while(!(SPSR & (1 << SPIF)));
data = SPDR;
return data;
}
int main(void) {
SPI_Init();
//PC0 y PC1 como salidas para los leds
DDRC |= (1 << PC0) | (1 << PC1);
while(1) {
PORTC = read_74HC165();
}
}
Si queremos podemos conectar varios modulos 74HC165 en cascada, de manera que la información de uno pasa a traves del otro, solo tenemos que conectar la salida Q7 de un modulo a la entrada DS del otro, la salida (Q7) del último módulo irá conectada al microcontrolador, de esta manera podemos leer 16 entradas en vez de 8, a la hora de hacer la lectura a traves del SPI tendremos que leer 2 bytes en lugar de 1 para leer los dos módulos.
#include <avr/io.h>
#include <util/delay.h>
void SPI_Init() {
DDRB |= (1 << PB5) | (1 << PB3) | (1 << PB2);
DDRB &= ~(1 << PB4);
// Habilita SPI, Modo Maestro, Velocidad fck/16
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0);
}
uint16_t read_74HC165() {
uint16_t data;
// Pulso en PL para cargar los datos paralelos
PORTB &= ~(1 << PB2);
//_delay_us(1); // Opcional? descomentar en caso de que el latch no funcione
PORTB |= (1 << PB2);
// Iniciar transmisión SPI (enviamos dummy data para recibir)
// En este caso lo único que necesitamos aquí es generar los pulsos de reloj para recibir la informacion.
SPDR = 0x00;
// Esperar a que termine la transferencia
while(!(SPSR & (1 << SPIF)));
data = SPDR;
// Leemos el segundo byte
SPDR = 0x00;
while(!(SPSR & (1 << SPIF)));
data = data | (uint16_t)SPDR << 8;
return data;
}
int main(void) {
SPI_Init();
//PC0 y PC1 como salidas para los leds
DDRC |= (1 << PC0);
DDRD |= (1 << PD0);
uint16_t inputs_status;
while(1) {
inputs_status = read_74HC165();
PORTC = (uint8_t) inputs_status;
PORTD = (uint8_t) (inputs_status>>8);
}
}
AVR | Parallel | Serie | 74HC165